package cloud.xlh.my_system.login.facial_recognition.service.impl;


import cloud.xlh.my_system.login.facial_recognition.service.FacialRecognitionService;
import cloud.xlh.my_system.mapper.login.facial_recognition.FacialRecognitionMapper;
import cloud.xlh.my_system.pojo.User;
import com.baidu.aip.face.AipFace;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Decoder;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2022/6/26 20:15
 * @ Description:
 */
@Service
@Transactional
public class FacialRecognitionServiceImpl implements FacialRecognitionService {
    @Autowired
    private FacialRecognitionMapper facialRecognitionMapper;

    private static final String APP_ID = "25323475";

    private static final String API_KEY = "GybckTSWCZqMceGPkLCvr3pi";

    private static final String SECRET_KEY = "okV2R8gIbl5dZGUEYBBa7VpMOUEiYjSO";

    @Override
    public String register(String userName, String faceBase) throws FileNotFoundException {
        if(!StringUtils.isEmpty(userName) && !StringUtils.isEmpty(faceBase)) {
            //文件上传的地址
            String upPath = ResourceUtils.getURL("classpath:").getPath()+"static\\photo";
            //用于查看路径是否正确
            System.out.println(upPath);
            // 图片名称
            String fileName = userName+System.currentTimeMillis() + ".png";
            System.out.println(upPath+"\\"+fileName);
            File file = new File(upPath+"\\"+fileName);
            //初始化百度云的AipFace
            AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY);

            //往自己demo数据库里插入一条用户数据
            User user = new User();
            user.setId(UUID.randomUUID().toString());
            user.setName(userName);
            user.setPhoto(upPath+"\\"+fileName);
            User exitUser = facialRecognitionMapper.findUserByName(userName);
            if(exitUser != null) {
                return "2";
            }
            facialRecognitionMapper.addUsers(user);

            // 往自己demo服务器里面上传摄像头捕获的图片
            GenerateImage(faceBase, file);
            //向百度云人脸库插入一张人脸
            facesetAddUser(client,faceBase,userName);
        }
        return "1";
    }

    @Override
    public String login(String faceBase) {
        String faceData = faceBase;
        //进行人像数据对比
        AipFace client = new AipFace(APP_ID,API_KEY,SECRET_KEY);
        Double num = verifyUser(faceData,client);
        if(num>95) {
            return "1";
        }else {
            return "2";
        }
    }

    /**
     *
     * @Title: GenerateImage
     * @Description: 该方法的主要作用：// 对字节数组字符串进行Base64解码并生成图片,并上传至服务器
     * @param  @param imgStr
     * @param  @param imgFilePath
     * @param  @return 设定文件
     * @return  返回类型：boolean
     * @throws
     */
    public boolean GenerateImage(String imgStr, File file) {
        // 图像数据为空
        if (imgStr == null) {
            return false;
        }else {
            @SuppressWarnings("restriction")
            BASE64Decoder decoder = new BASE64Decoder();
            try {
                // Base64解码
                @SuppressWarnings("restriction")
                byte[] bytes = decoder.decodeBuffer(imgStr);
                for (int i = 0; i < bytes.length; ++i) {
                    if (bytes[i] < 0) {
                        bytes[i] += 256;
                    }
                }
                // 生成jpeg图片
                if(!file.exists()) {
                    file.getParentFile().mkdir();
                    OutputStream out = new FileOutputStream(file);
                    out.write(bytes);
                    out.flush();
                    out.close();
                    return true;
                }

            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }

    /**
     * @Title: facesetAddUser
     * @Description: 该方法的主要作用：人脸注册,给人脸库中注册一个人脸
     * @param  @param client 设定文件
     * @return  返回类型：void
     * @throws
     */
    public boolean facesetAddUser(AipFace client, String faceBase, String username) {
        // 参数为数据库中注册的人脸
        HashMap<String, String> options = new HashMap<String, String>();
        options.put("user_info", "user's info");
        JSONObject res = client.addUser(faceBase, "BASE64", "user_01", username, options);
        System.out.println(res.toString(2));
        return true;

    }

    /**
     * 人脸比对
     * @param imgBash64 照片转bash64格式
     * @param imgType 类型
     * @param groupList 百度云人脸识别用户组
     * @return
     */
    public Double verifyUser(String imgBash64,AipFace client) {
        // 传入可选参数调用接口
        HashMap<String, String> options = new HashMap<String, String>();

        JSONObject res = client.search(imgBash64, "BASE64", "user_01", options);
        System.out.println(res.toString(2));
        try {
            System.out.println(res.getJSONObject("result"));
        }catch (Exception e) {
            return 80.0;
        }
        System.out.println(res.getJSONObject("result").getJSONArray("user_list"));
        JSONObject user = (JSONObject) res.getJSONObject("result").getJSONArray("user_list").get(0);
        Double score = (Double) user.get("score");

        return score;
    }
}
